/**
 * 
 */
package com.toncen.samepms.interceptor;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.toncen.samepms.common.ComitConstant;
import com.toncen.samepms.common.IDatabaseActionable;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

/**
 * 事务拦截器：在action的方法执行前后开启和关闭事务，方法执行失败回滚事务
 * 
 * @author tch
 * 
 */
public class TransactionInterceptor extends MethodFilterInterceptor {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4759165676819171063L;

	protected Log logger = LogFactory.getLog(this.getClass());

	/**
	 * 
	 */
	public TransactionInterceptor() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.interceptor.MethodFilterInterceptor#doIntercept(com.opensymphony.xwork2.ActionInvocation)
	 */
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		if (invocation.getAction() instanceof IDatabaseActionable) {// 是数据库操作的Action
			IDatabaseActionable action = (IDatabaseActionable) invocation.getAction();
			String result = "";
			Method actionMethod = action.getClass().getMethod(invocation.getProxy().getMethod());
			Transaction transaction = actionMethod.getAnnotation(Transaction.class);
			if (transaction != null) {// 事务处理
				if (action.getDao() == null) {
					throw new IllegalArgumentException("【" + action.getClass().getName() + "】没有设置Dao，请与系统管理员联系...");
				}
				try {
					action.getDao().beginTransaction();
					outInfo(invocation.getAction(), action.getClass().getSimpleName() + " begin Transaction...");
					result = invocation.invoke();
					action.getDao().commitTransaction();
					outInfo(invocation.getAction(), action.getClass().getSimpleName() + " commit Transaction...");
				} catch (Throwable e) {
					e.printStackTrace();
					action.getDao().rollback();
					outInfo(invocation.getAction(), action.getClass().getSimpleName() + " rollback Transaction...");
					if (e instanceof Exception) {
						throw (Exception) e;
					} else {
						throw new RuntimeException(e);
					}
				} finally {
					action.getDao().endTransaction();
					outInfo(invocation.getAction(), action.getClass().getSimpleName() + " end Transaction...");
				}
			} else {
				result = invocation.invoke();
			}
			return result;
		} else {
			return invocation.invoke();
		}
	}

	/**
	 * @param targetObj
	 * @param content
	 */
	private void outInfo(Object targetObj, Object content) {
		if (ComitConstant.isDeveloperMode()) {
			System.out.println("[" + targetObj.getClass().getSimpleName() + "]:" + content);
		}
	}
}
